package biz

import (
	"context"
	"github.com/go-kratos/kratos/v2/log"
	amount_v1 "gorm_transaction/api/Amount1Server/v1"
)

type Amount1BizInterface interface {
	// 编辑库存
	EditOrderMain(ctx context.Context, id uint32, changeValue int64) error
	EditOrderMainWithTX(ctx context.Context, id uint32, changeValue int64) error
	// 编辑流水
	AddOrderStatement(ctx context.Context, orderMainId uint32, changeValue int64, orderNo string) error
	AddOrderStatementWithTX(ctx context.Context, orderMainId uint32, changeValue int64, orderNo string) error
	// 删除流水
	DelOrderStatement(ctx context.Context, id uint32, orderNo string) error
	DelOrderStatementWithTX(ctx context.Context, id uint32, orderNo string) error
}

type Amount1BizStruct struct {
	amount1Repo Amount1BizInterface
	logger      log.Logger
	// Notice 事务
	TM Transaction
}

func NewAmount1Biz(biz Amount1BizInterface, logger log.Logger, tm Transaction) *Amount1BizStruct {
	return &Amount1BizStruct{
		amount1Repo: biz,
		logger:      logger,
		TM:          tm,
	}
}

func (a *Amount1BizStruct) TransOutOrder(ctx context.Context, req *amount_v1.TransOutOrderRequest) (*amount_v1.Empty, error) {
	reply := &amount_v1.Empty{}

	// 在本地事务中执行：修改 order_main表、在order_statement表中新增记录
	errTransaction := a.TM.InTx(ctx, func(ctx context.Context) error {
		// 这里需要从ctx中获取tx
		err1 := a.amount1Repo.EditOrderMainWithTX(ctx, req.Id, req.StockChange)
		if err1 != nil {
			return err1
		}

		err2 := a.amount1Repo.AddOrderStatementWithTX(ctx, req.Id, req.StockChange, req.OrderNo)
		if err2 != nil {
			return err2
		}

		return nil
	})

	if errTransaction != nil {
		return nil, errTransaction
	}

	return reply, nil
}

func (a *Amount1BizStruct) TransOutOrderCompensate(ctx context.Context, req *amount_v1.TransOutOrderCompensateRequest) (*amount_v1.Empty, error) {
	reply := &amount_v1.Empty{}

	// 在本地事务中执行：修改order_main表、删除order_statement表中对应的流水记录
	errTransaction := a.TM.InTx(ctx, func(ctx context.Context) error {
		err1 := a.amount1Repo.EditOrderMainWithTX(ctx, req.Id, req.StockChange)
		if err1 != nil {
			return err1
		}

		err2 := a.amount1Repo.DelOrderStatementWithTX(ctx, req.Id, req.OrderNo)
		if err2 != nil {
			return err2
		}

		return nil
	})

	if errTransaction != nil {
		return nil, errTransaction
	}

	return reply, nil
}
